#include <stdio.h>
#include <vector>
using namespace std;

const int V = 100000;
int parent[V];
bool used[V];

struct Edge
{
	int src, des;
};
vector<Edge> edges;

int root(int& v)
{
	int depth = 0;
	while (parent[v] != -1)
	{
		v = parent[v];
		++depth;
	}
	return depth;
}

bool merge(int& a, int& b)
{
	int d1 = root(a);
	int d2 = root(b);
	if (a == b)
		return false;

	if (d1 < d2)
		parent[a] = b;
	else
		parent[b] = a;

	return true;
}

int main()
{
	while (1)
	{
		int max = 0;
		int n = 0;
		edges.clear();
		while (1)
		{
			Edge e;
			scanf ("%d %d", &e.src, &e.des);
			if (e.src == -1 && e.des == -1)
				return 0;
			if (e.src == 0 && e.des == 0)
				break;

			--e.src, --e.des;
			edges.push_back(e);
			if (e.src > max)
				max = e.src;
			if (e.des > max)
				max = e.des;
			if (used[e.src] == 0)
			{
				++n;
				++used[e.src];
			}
			if (used[e.des] == 0)
			{
				++n;
				++used[e.des];
			}
		}

		bool yes = true;
		if (edges.size() == 0)
			yes = true;
		else if (edges.size() != n - 1)
			yes = false;
		else
		{
			for (int i = 0; i < n; ++i)
				parent[i] = -1;

			for (vector<Edge>::iterator it = edges.begin(); it != edges.end(); ++it)
			{
				if (!merge(it->src, it->des))
				{
					yes = false;
					break;
				}
			}
		}

		if (yes)
			printf ("Yes\n");
		else
			printf ("No\n");

		for (int i = 0; i <= max; ++i)
			used[i] = 0;
	}
	return 0;
}